package com.gzhu.knowledgeAdmin.parammanage;

import com.gzhu.knowledgeAdmin.common.dto.param.ParamAddRequest;
import com.gzhu.knowledgeAdmin.common.dto.param.ParamDeleteRequest;
import com.gzhu.knowledgeAdmin.common.dto.param.ParamGetRequest;
import com.gzhu.knowledgeAdmin.common.exception.BusinessException;
import com.gzhu.knowledgeAdmin.common.result.ErrorCode;
import com.gzhu.knowledgeAdmin.common.vo.TemplateExternalVO;
import com.gzhu.knowledgeAdmin.entity.Recorder;
import com.gzhu.knowledgeAdmin.entity.Template;
import com.gzhu.knowledgeAdmin.repository.RecorderRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class RecorderParamCRUD implements ParamCRUD<Recorder>{

    @Autowired
    private RecorderRepository recorderRepository;

    @Autowired
    private RecorderCache recorderCache;

    @Override
    public List<String> getSimpleList() {
        List<Recorder> recorderList = recorderRepository.findAll();
        return recorderList.stream().map(recorder -> recorder.getName()).collect(Collectors.toList());
    }

    @Override
    public org.springframework.data.domain.Page<Recorder> getList(ParamGetRequest paramGetRequest) {
        Recorder recorder = new Recorder();
        recorder.setName(paramGetRequest.getValue());

        ExampleMatcher matcher = ExampleMatcher.matching()
                //contains 模糊匹配
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains());

        Example<Recorder> example = Example.of(recorder, matcher);

        Pageable pageable = PageRequest.of(paramGetRequest.getPageNum() - 1, paramGetRequest.getPageSize());
        return recorderRepository.findAll(example, pageable);
    }

    @Override
    public void addParam(ParamAddRequest paramAddRequest) {
        String value = paramAddRequest.getValue();

        Recorder recorderByName = recorderRepository.getRecorderByName(value);

        if (recorderByName != null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"对应参数已经存在");
        }

        Recorder recorder = new Recorder();
        recorder.setAiId(paramAddRequest.getAiId());
        recorder.setName(value);

        recorderRepository.save(recorder);

        recorderCache.putCache(recorder.getName(), recorder.getAiId());
    }

    @Override
    public void deleteParam(ParamDeleteRequest paramDeleteRequest) {
        List<Integer> ids = paramDeleteRequest.getIds();
        recorderRepository.deleteAllByIdInBatch(ids);

        recorderCache.deleteCache();
    }

    public List<TemplateExternalVO> fillRecorderParam(List<Template> list) {
        List<TemplateExternalVO> result = list.stream().filter(Objects::nonNull).map(template -> {
            TemplateExternalVO templateExternalVO = new TemplateExternalVO();
            BeanUtils.copyProperties(template, templateExternalVO);
            templateExternalVO.setAiId(recorderCache.getAiIdByRecorderName(template.getRecorder()));
            return templateExternalVO;
        }).collect(Collectors.toList());

        if (result.isEmpty()) {
            result.add(null);
        }
        return result;
    }

    public Map<String, Integer> getRecorderName2AiIdMap(List<Template> list) {
        Map<String, List<Template>> recorder2TemplateListMap = list.stream().collect(Collectors.groupingBy(Template::getRecorder));
        Set<String> recorderSet = recorder2TemplateListMap.keySet();
        List<Recorder> recorderByNameIn = recorderRepository.getRecorderByNameIn(recorderSet);
        Map<String, Integer> name2AiIdMap = recorderByNameIn.stream().collect(Collectors.toMap(Recorder::getName, Recorder::getAiId));

        return name2AiIdMap;
    }
}
